package com.qitmiaojie.service.impl;

import cn.hutool.json.JSONObject;
import com.baidubce.util.JsonUtils;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.qitmiaojie.controller.utils.Result;
import com.qitmiaojie.mapper.UserMapper;
import com.qitmiaojie.pojo.HealthCode;
import com.qitmiaojie.pojo.Temperature;
import com.qitmiaojie.pojo.User;
import com.qitmiaojie.pojo.dto.TemperatureHealthCode;
import com.qitmiaojie.service.TemperatureService;
import com.qitmiaojie.mapper.TemperatureMapper;
import com.qitmiaojie.test.RecognizeHealthCodeOCR;
import com.qitmiaojie.utils.BeanCopyUtils;
import com.tencentcloudapi.common.exception.TencentCloudSDKException;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.formula.functions.T;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;

import java.io.IOException;
import java.util.*;
import java.util.concurrent.CountDownLatch;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 *
 */
@Service
@Slf4j
public class TemperatureServiceImpl extends ServiceImpl<TemperatureMapper, Temperature>
    implements TemperatureService{

    @Autowired
    private UserMapper userMapper;

    @Override
    public Result addTemperature(Temperature temperature) {
        User CONTEXT_USER = userMapper.selectByUsername(SecurityContextHolder.getContext().getAuthentication().getPrincipal().toString());
        LambdaQueryWrapper<Temperature> queryWrapper = new LambdaQueryWrapper<>();
        temperature.setUserid(CONTEXT_USER.getId());
        queryWrapper.eq(Temperature::getUserid,CONTEXT_USER.getId());
        queryWrapper.eq(Temperature::getDay,temperature.getDay());
        Temperature one = getOne(queryWrapper);

        if (one != null){
            log.info("数据库中有数据！");
            removeById(one.getId());
            save(temperature);
        }else {
            save(temperature);
        }
        return Result.success("体温上报成功！",null);
    }

    @Override
    public Result getAllIsTemperature(String date) {
        User CONTEXT_USER = userMapper.selectByUsername(SecurityContextHolder.getContext().getAuthentication().getPrincipal().toString());
        LambdaQueryWrapper<Temperature> queryWrapper = new LambdaQueryWrapper<>();
        String dateBegin = date + "-1";//2022-7-1
        String dateEnd = date + "-31";//2022-7-31
        queryWrapper.eq(Temperature::getUserid,CONTEXT_USER.getId());
        queryWrapper.between(Temperature::getDay,dateBegin,dateEnd);
        List<Temperature> list = list(queryWrapper);
        List<Map<String, Object>> mapList = list.stream().map(new Function<Temperature, Map<String, Object>>() {
            @Override
            public Map<String, Object> apply(Temperature temperature) {
                // orderSettingMap.put("date",orderSetting.getOrderDate().getDate());//获得日期（几号）
                Map<String, Object> map = new HashMap<>();
                map.put("date", temperature.getDay().getDate());
                map.put("flag", true);
                return map;
            }
        }).collect(Collectors.toList());
        log.info(mapList.toString());
        return Result.success(mapList);
    }

    @Override
    public Result getTemperature(String today) {
        if (StringUtils.isEmpty(today)){
           return null;
        }
        User CONTEXT_USER = userMapper.selectByUsername(SecurityContextHolder.getContext().getAuthentication().getPrincipal().toString());
        log.info(today);
        int i = today.lastIndexOf(" ");
        log.info(today.substring(0,i));
        log.info(today.substring(0,i));
        LambdaQueryWrapper<Temperature> queryWrapper= new LambdaQueryWrapper<>();
        queryWrapper.eq(Temperature::getDay,today.substring(0,i));
        queryWrapper.eq(Temperature::getUserid,CONTEXT_USER.getId());
        Temperature temperature = getOne(queryWrapper);
        if (ObjectUtils.isEmpty(temperature)){
              return new Result(0,"请上报体温",null);
        }
        return Result.success(temperature);
    }

    @Override
    @Async
    public Result getAlltemperatureAndHealthCode(String date, String name, String status, String idNumber, String result, Integer currentPage, Integer size) throws IOException, TencentCloudSDKException, InterruptedException {

        IPage<Temperature> iPage = new Page<Temperature>(currentPage,size);
        String today = null;
        if (!StringUtils.isEmpty(date)){
            int i = date.lastIndexOf("-");
            today = date.substring(0,i+3);
        }
        LambdaQueryWrapper<Temperature> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.like(!StringUtils.isEmpty(today),Temperature::getDay,today);

        if (!StringUtils.isEmpty(name)){
            User user = userMapper.selectByUsername(name);
            queryWrapper.like(Temperature::getUserid,user.getId());
        }
        queryWrapper.like(!StringUtils.isEmpty(status),Temperature::getStatus,status);
        queryWrapper.orderByDesc(Temperature::getDay);
        page(iPage,queryWrapper);
        List<Temperature> records = iPage.getRecords();
        List<TemperatureHealthCode> list = Collections.synchronizedList(new ArrayList<>());


        if (StringUtils.isEmpty(date)){
            Map<String,Object> map = new HashMap<>();
            for (int i = 0; i < records.size(); i++) {
                TemperatureHealthCode temperatureHealthCode =
                        BeanCopyUtils.copyBean(records.get(i), TemperatureHealthCode.class);
                temperatureHealthCode.setUsername(
                        userMapper.QueryById(records.get(i).getUserid()).getUserName()
                );
                list.add(temperatureHealthCode);
            }

            map.put("data",list);
            map.put("TotalCount",iPage.getTotal());
            return Result.success(map);
        }else {
            for (int i = 0; i < records.size(); i++) {
                String json = null;
                try {
                    json = RecognizeHealthCodeOCR.recognizeHealthCodeOCR(records.get(i).getUrl());
                } catch (IOException e) {
                    e.printStackTrace();
                } catch (TencentCloudSDKException e) {
                    e.printStackTrace();
                }
                HealthCode healthCode = JsonUtils.fromJsonString(json, HealthCode.class);
                TemperatureHealthCode temperatureHealthCode = BeanCopyUtils.copyBean(records.get(i), TemperatureHealthCode.class);
                temperatureHealthCode.setHealthCode(JsonUtils.fromJsonString(json, HealthCode.class));
                temperatureHealthCode.setUsername(userMapper.QueryById(records.get(i).getUserid()).getUserName());
                log.info(json);
                list.add(temperatureHealthCode);
                Map<String,Object> map = new HashMap<>();
                map.put("data",list);
                map.put("TotalCount",iPage.getTotal());
                return Result.success(map);
            }
        }


 /*       ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
       // List<Object> list = Collections.synchronizedList(new ArrayList<>());

        //CountDownLatch能够使一个线程在等待另外一些线程完成各自工作之后，
        // 再继续执行。使用一个计数器进行实现。计数器初始值为线程的数量。
        // 当每一个线程完成自己任务后，计数器的值就会减一。
        // 当计数器的值为0时，表示所有的线程都已经完成一些任务，
        // 然后在CountDownLatch上等待的线程就可以恢复执行接下来的任务
        long start = System.currentTimeMillis();
        int threadCount = records.size();
        CountDownLatch latch = new CountDownLatch(threadCount);
        for (int i = 0; i < threadCount; i++) {
            int finalI = i;
            new Thread(new Runnable() {
                @SneakyThrows
                @Override
                public void run() {
                    String json = RecognizeHealthCodeOCR.recognizeHealthCodeOCR(records.get(finalI).getUrl());
                    HealthCode healthCode = JsonUtils.fromJsonString(json, HealthCode.class);
                    TemperatureHealthCode temperatureHealthCode = BeanCopyUtils.copyBean(records.get(finalI), TemperatureHealthCode.class);
                    temperatureHealthCode.setHealthCode(JsonUtils.fromJsonString(json, HealthCode.class));
                    temperatureHealthCode.setUsername(userMapper.QueryById(records.get(finalI).getUserid()).getUserName());
                    log.info(json);
                    list.add(temperatureHealthCode);
                    //计数器减一
                    latch.countDown();
                }
            }).start();
        }
        //阻塞当前线程，直到计数器的值为0
        latch.await();
        long end = System.currentTimeMillis();
        log.info("{},{}",list.size(),end=start);
        log.info(list.toString());*/

        return null;
    }
}




